package com.mine.frame.mylandemo.ui.mqtt

import android.content.Context
import android.util.Log
import com.third.device.mg.serialport.utils.toHexString
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.*

/**
 * @Date 2022/5/24
 * Description:
 *
 * QOS
另外还有一个比较重要的概念就是QOS（服务质量），这里有3个值（0,1,2），代表的意义如下：
0：代表，Sender 发送的一条消息，Receiver 最多能收到一次，也就是说 Sender 尽力向 Receiver 发送消息，如果发送失败，也就算了。
1：代表，Sender 发送的一条消息，Receiver 至少能收到一次，也就是说 Sender 向 Receiver 发送消息，如果发送失败，会继续重试，直到 Receiver 收到消息为止，但是因为重传的原因，Receiver 有可能会收到重复的消息。
2：代表，Sender 发送的一条消息，Receiver 确保能收到而且只收到一次，也就是说 Sender 尽力向 Receiver 发送消息，如果发送失败，会继续重试，直到 Receiver 收到消息为止，同时保证 Receiver 不会因为消息重传而收到重复的消息。

 */
class MqttClientUtils private constructor() {

    private lateinit var mMqttClient: MqttAndroidClient
    private var isConnect = false

    private val clientId = "123464652"
    private val gwAddress = "EC:C5:7F:13:D9:D3"
    //下发主题
    private val sentTopic = "server2gw/cmd/$gwAddress"
    //订阅主题
    private val reportTopic = "gw2server/event"

    private val serverURI = "tcp://47.96.77.210:1883"

    private val userName = "admin"
    private val password = "ca83KcaJcS2hXFNU"

    companion object {
        const val TAG = "MqttClientUtils: "
        fun getInstance(): MqttClientUtils = MqttClientHolder.instance
    }

    private object MqttClientHolder {
        val instance = MqttClientUtils()
    }


    fun connectMQTT(context: Context) {
        mMqttClient = MqttAndroidClient(context, serverURI, clientId)
        val options = MqttConnectOptions()
        //设置自动重连
        options.isAutomaticReconnect = true
        // 缓存,
        options.isCleanSession = true
        // 设置超时时间，单位：秒
        options.connectionTimeout = 15
        // 心跳包发送间隔，单位：秒
        options.keepAliveInterval = 15
        // 用户名
        options.userName = userName
        // 密码
        options.password = password.toCharArray()
        // 设置MQTT监听
        mMqttClient.setCallback(object : MqttCallback {
            override fun connectionLost(cause: Throwable?) {
                Log.d(TAG, "connectionLost: 连接断开")
                isConnect = false
            }

            override fun messageArrived(topic: String?, message: MqttMessage?) {
                Log.d(TAG, "消息到达 ==>> topic: $topic   payload: ${message?.payload?.toHexString()}")
            }

            override fun deliveryComplete(token: IMqttDeliveryToken?) {
                Log.d(TAG, "投递完成")
            }
        })

        mMqttClient.connect(options, null, object : IMqttActionListener {
            override fun onSuccess(asyncActionToken: IMqttToken?) {
                Log.d(TAG, "onSuccess: 连接成功 ,可以订阅消息和发送消息了")
                isConnect = true
                mMqttClient.subscribe(reportTopic ,2)
            }

            override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
                Log.d(TAG, "onFailure: 连接失败")
                isConnect = false
                exception?.printStackTrace()
            }
        })
    }


    /**
     * 发布
     */
    fun publish(message: ByteArray) {
        if (isConnect) {
            val msg = MqttMessage()
            msg.isRetained = false
            msg.payload = message
            msg.qos = 1
            mMqttClient.publish(sentTopic, msg)
        }
    }



    /**
     * 断开连接
     */
    fun disconnect() {
        if (this::mMqttClient.isInitialized && mMqttClient.isConnected)
            mMqttClient.disconnect()
    }

}